package com.wanger.swc.util.myEnum;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.StrUtil;
import com.wanger.swc.exception.BusEx;
import com.wanger.swc.util.json.MyJson;
import com.wanger.swc.util.json.MyMap;
import lombok.Data;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: wanger
 * @Date: 2024/12/13 10:33
 * @Description:
 */
@Data
public class MyEnumUtil<T extends BaseEnum> {
    private MyEnumUtil() {
    }

    public static <T extends BaseEnum> MyEnumUtil<T> create(T[] values) {
        MyEnumUtil<T> util = new MyEnumUtil<>();
        util.initialize(values);
        return util;
    }

    private final Map<String, List<Map<String, String>>> list = new HashMap<>();
    private final Map<String, Map<String, T>> map = new HashMap<>();

    @SuppressWarnings("all")
    private void initialize(T[] values) {
        for (T value : values) {
            list.merge(value.getField(),
                    new ArrayList<Map<String, String>>() {{
                        add(new HashMap<String, String>() {{
                            put(LambdaUtil.getFieldName(T::getValue), value.getValue());
                            put(LambdaUtil.getFieldName(T::getLabel), value.getLabel());
                        }});
                    }}, (l1, l2) -> {
                        l1.addAll(l2);
                        return l1;
                    });
            map.merge(value.getField(),
                    new HashMap<String, T>() {{
                        put(value.getValue(), value);
                    }}, (l1, l2) -> {
                        l1.putAll(l2);
                        return l1;
                    });
        }
    }

    public Map<String, T> getMapByField(String field) {
        Map<String, T> enumMap = map.get(field);
        if (CollUtil.isEmpty(enumMap)) BusEx.throwEx("field【" + field + "】没有找到对应的枚举");
        return enumMap;
    }

    public T getEnumByFieldAndCode(String field, String code) {
        T anEnum = getMapByField(field).get(code);
        if (anEnum == null) {
            MyMap tData = MyJson.map()
                    .pu("field", field)
                    .pu("code", code)
                    .pu("enums", this.map.get(field)
                            .entrySet()
                            .stream()
                            .map(e -> e.getKey() + ":" + e.getValue().getLabel())
                            .collect(Collectors.joining(",")));
            String msg = StrUtil.format(
                    "field【{field}】入参枚举类型【{code}】未找到，field【{field}】对应的枚举有【{enums}】",
                    tData
            );
            BusEx.throwEx(msg);
        }
        return anEnum;
    }

    public T getEnumByFieldAndCode(Func0<String> getFunc) {
        return getEnumByFieldAndCode(LambdaUtil.getFieldName(getFunc), getFunc.callWithRuntimeException());
    }

    public String getEnumName(Func0<String> getFunc) {
        String code = getFunc.callWithRuntimeException();
        if (StrUtil.isNotBlank(code)) {
            return getEnumByFieldAndCode(LambdaUtil.getFieldName(getFunc), code).getLabel();
        } else return null;
    }
}
